<template>
  <div class="datepicker-container">
    <input type="text" class="form-control" readonly
      :name="name"
      :value="_dateFormat(this.current)"
      @click.stop="show = !show">
      <!-- 删除按钮 -->
    <!-- <span class="ico-delete" v-if="value != ' '" @click="_cancelVal(this.current)">X</span> -->
    <span class="ico-calendar"></span>
    <div class="datepicker-wrap" v-show="show">
      <div class="datepicker-hd">
        <button class="prev" @click.stop="switchMonth(-1)"></button>
        <span class="cur-date">
          {{select.year}} 年 {{select.month}} 月
        </span>
        <button class="next" @click.stop="switchMonth(1)"></button>
      </div>
      <div class="datepicker-ct">
        <table>
          <thead>
            <tr>
              <th>日</th>
              <th>一</th>
              <th>二</th>
              <th>三</th>
              <th>四</th>
              <th>五</th>
              <th>六</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(week, index) in list" :key="index">
              <td v-for="(weekday, key) in week" 
                :key="key"
                :class="{flag: weekday.flag, active: !weekday.flag && weekday.text == current.date && select.month == current.month && select.year == current.year}"
                @click.stop="onPicker(weekday)">
                <span v-text="weekday.text"></span>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    props: {
      value: {
        type: [String, Number]
      },
      name: {
        type: String,
        default: null
      }
    },
    data() {
      return {
        show: false,
        current: '',    // 已选择的日期时间。yyyy-MM-dd
        select: {       // 已选择的日期对象
          year: '',
          month: '',
          date: '',
          day: ''
        },
        currentMonthFirstDay: null, // 当前月的1号属于星期几
        currentMonthEndDate: null,  // 当前月的最后一天是几号
        currentMonthEndDay: null,   // 当前月的最后一天属于星期几
        lastMonthEndDate: null,     // 上个月的最后一天是几号
        list: [],   // 日历的二维数组
        years: [],  // 1900-2100
        months: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
      }
    },
    watch: {
      select: {
        handler(newVal) {
          let pre
          if (newVal.month === 1) {
            pre = new Date(newVal.year - 1, 12, 0)
          } else {
            pre = new Date(newVal.year, newVal.month - 1, 0)
          }
          this.lastMonthEndDate = pre.getDate()
          // 获取日历排表
          this.getDateList()
        },
        deep: true
      },
      show(newVal) {
        if (newVal) {
          document.addEventListener('click', this._hideDatePicker, false)
        }
      }
    },
    created() {
      if (!this.value) {
        this.transform(new Date().getTime())
      } else if (this.value && typeof this.value === 'number') {
        this.transform(this.value)
      }
      setTimeout(() => {
        this._complate()
      }, 14)
      // 获得年份列表： 1900-2100
      for (let i = 1900; i <= 2100; i++) {
        this.years.push(i)
      }
    },
    methods: {
      // _cancelVal(val) {
      //   this.current = {
      //     year: '',
      //     month: '',
      //     date: ''
      //   }
      //   this.$emit('input', this._dateFormat(this.current))
      // },
      // 将时间转化为具体的 年、月、日、星期
      transform(time) {
        const date = new Date(time)
        this.select.year = date.getFullYear()
        this.select.month = date.getMonth() + 1
        this.select.date = date.getDate()
        this.select.day = date.getDay()
        this.currentMonthFirstDay =
          new Date(this.select.year, this.select.month - 1, 1, 0).getDay()
        this.currentMonthEndDate =
          new Date(this.select.year, this.select.month, 0).getDate()
        this.currentMonthEndDay =
          new Date(this.select.year, this.select.month, 0).getDay()
      },
      /*
      * 计算出日历列表，二维数组
      * 第一层为星期，第二层为每星期的第几天
      */
      getDateList() {
        this.list = []
        // 获取日历第一行的数据（需加上第一个星期中所包含上个月的几天）
        let temp = this.lastMonthEndDate - (this.currentMonthFirstDay - 1)
        let list = this.numberList(temp, this.lastMonthEndDate, true).concat(this.numberList(1, 7 - this.currentMonthFirstDay))
        this.list.push(list)
        temp = (7 - this.currentMonthFirstDay) + 1
        // 剩下的行数 计算除了第一行剩下的天数
        const leftDays = this.currentMonthEndDate - (7 - this.currentMonthFirstDay)
        // 剩下的星期数
        const lineNumber = Math.ceil(leftDays / 7)
        // 包含下个月日历的天数
        const nextDays = 7 - (leftDays % 7)
        for (let i = 0; i < lineNumber; i++) {
          if (i === lineNumber - 1 && nextDays > 0 && nextDays !== 7) {
            this.list[lineNumber] = this.numberList(temp, this.currentMonthEndDate).concat(this.numberList(1, nextDays, true))
          } else {
            this.list.push(this.numberList(temp, temp + 6))
          }
          temp = temp + 7
        }
      },
      /*
      * 获得日历数组
      * start: 开始日
      * end: 结束日
      * flag： boolean值，判断是否属于本月
      */
      numberList(start, end, flag) {
        let list = []
        for (let i = start; i <= end; i++) {
          list.push({
            text: i,
            flag: flag
          })
        }
        return list
      },
      // 切换月份， -1为当前月份-1，+1为当前月份+1
      switchMonth(n) {
        let year = this.select.year
        if (n === -1) {
          const pre = this.select.month === 1 ? 12 : this.select.month - 1
          if (pre === 12) {
            this.transform(new Date(year - 1, pre - 1, this.select.date))
          } else {
            this.transform(new Date(year, pre - 1, this.select.date))
          }
        } else {
          const next = this.select.month === 12 ? 1 : this.select.month + 1
          if (next === 1) {
            this.transform(new Date(year + 1, next - 1, this.select.date))
          } else {
            this.transform(new Date(year, next - 1, this.select.date))
          }
        }
      },
      onPicker(day) {
        if (day.flag) {
          // 当页日历上可能还会显示部分上个月或者下个月的部分天数，根据标识来做判断
          // 并对月份作出相应的处理
          if (parseInt(day.text) > 15) {
            this.transform(new Date(this.select.year, this.select.month - 2, parseInt(day.text)))
          } else {
            this.transform(new Date(this.select.year, this.select.month, parseInt(day.text)))
          }
        } else {
          this.transform(new Date(this.select.year, this.select.month - 1, parseInt(day.text)))
        }
        this._complate()
        this.show = false
      },
      _complate() {
        if (!this.value) {
          this.current = {
            year: '',
            month: '',
            date: ''
          }
        } else {
          this.current = {
            year: this.select.year,
            month: this.select.month,
            date: this.select.date
          }
        }
        this.$emit('input', this._dateFormat(this.current))
      },
      _dateFormat(val) {
        if (!val) return ''
        return `${val.year}-${val.month}-${val.date}`.replace(/\d+/g, (a) => {
          return (a.length === 4) ? a : ((a.length === 2) ? a : ('0' + a))
        })
      },
      _hideDatePicker() {
        this.show = false
      }
    },
    destroyed() {
      document.removeEventListener('click', this._hideDatePicker, false)
    }
  }
</script>

<style lang="scss">
  .datepicker-container {
    position: relative;
    .form-control {
      line-height: 34px;
    }
    .ico-delete {
      position: absolute;
      cursor: pointer;
      top: 6px;
      right: 20px;
      width: 14px;
      height: 14px;
    }
    .ico-calendar {
      position: absolute;
      top: 10px;
      right: 10px;
      width: 14px;
      height: 14px;
      background: url('./calendar.png') no-repeat;
      background-size: cover;
    }
  }
  .datepicker-wrap {
    position: absolute;
    z-index: 1;
    width: 100%;
    min-width: 290px;
    padding: 6px 10px;
    border: 1px solid #eee;
    background: #fff;
  }
  .datepicker-hd {
    line-height: 36px;
    font-size: 14px;
    text-align: center;
    color: #5e7a88;
    .prev {
      background-image: url('./prev.png');
      float: left;
    }
    .next {
      background-image: url('./next.png');
      float: right;
    }
    .prev, .next {
      width: 36px;
      height: 36px;
      background-size: 16px 16px;
      background-position: center center;
      background-repeat: no-repeat;
      cursor: pointer;
    }
  }
  .datepicker-ct {
    position: relative;
    table {
      width: 100%;
      border-collapse: collapse;
      color: #444;
      th {
        height: 30px;
        font-size: 10px;
      }
      td {
        height: 34px;
        text-align: center;
        cursor: pointer;
        span {
          width: 80%;
          border-radius: 3px;
        }
        &.active,
        &.active:hover {
          span {
            color: #fff;
            background: #5e7a88;
          }
        }
        &.flag {
          color: #ccc;
        }
        &:hover {
          span {
            background: #f3f8fa;
          }
        }
        span {
          display: block;
          max-width: 40px;
          margin: 0 auto;
          height: 24px;
          line-height: 24px;
          border-radius: 2px;
          font-size: 14px;
        }
      }
    }
  }
</style>
